package no.ntnu.fp.connection;

import java.util.HashMap;
import java.util.Map;

import no.ntnu.fp.handler.Handler;
import no.ntnu.fp.messages.Message;
import no.ntnu.fp.messages.MessageCode;
import no.ntnu.fp.messages.impl.AcceptNoticeMessage;
import no.ntnu.fp.messages.impl.AddMeetingMessage;
import no.ntnu.fp.messages.impl.AddOrUpdateAppointmentMessage;
import no.ntnu.fp.messages.impl.AlreadyLoggedInMessage;
import no.ntnu.fp.messages.impl.AppointmentAddedOrUpdatedMessage;
import no.ntnu.fp.messages.impl.AppointmentDeletedMessage;
import no.ntnu.fp.messages.impl.AppointmentsForEmployeeMessage;
import no.ntnu.fp.messages.impl.DeleteAppointmentMessage;
import no.ntnu.fp.messages.impl.DeleteMeetingMessage;
import no.ntnu.fp.messages.impl.EmployeesFetchedMessage;
import no.ntnu.fp.messages.impl.GetEmployeesMessage;
import no.ntnu.fp.messages.impl.GetMeetingRoomsMessage;
import no.ntnu.fp.messages.impl.LoginFailedMessage;
import no.ntnu.fp.messages.impl.LoginMessage;
import no.ntnu.fp.messages.impl.LoginSuccessfulMessage;
import no.ntnu.fp.messages.impl.LogoutMessage;
import no.ntnu.fp.messages.impl.LogoutSuccessfulMessage;
import no.ntnu.fp.messages.impl.MeetingAddedMessage;
import no.ntnu.fp.messages.impl.MeetingDeletedMessage;
import no.ntnu.fp.messages.impl.MeetingRejectedMessage;
import no.ntnu.fp.messages.impl.MeetingRoomsFetchedMessage;
import no.ntnu.fp.messages.impl.MeetingUpdatedMessage;
import no.ntnu.fp.messages.impl.MeetingsForEmployeeMessage;
import no.ntnu.fp.messages.impl.NoticeAddedOrUpdatedMessage;
import no.ntnu.fp.messages.impl.NoticeReadMessage;
import no.ntnu.fp.messages.impl.RejectNoticeMessage;
import no.ntnu.fp.messages.impl.RequestAppointmentsForEmployeeMessage;
import no.ntnu.fp.messages.impl.RequestMeetingsForEmployeeMessage;
import no.ntnu.fp.messages.impl.UpdateMeetingMessage;


/**
 * Initializer class. Must be extended and implemented in each project
 * in order to registers different {@link Handler}s with different {@link MessageCode}s. 
 * @author benjamin
 *
 */
public abstract class Initializer {
	public void initialize() {
		MessageTranslator.createInstance(getMessageCodeMapping());
		MessageHandler.createInstance(getMessageHandlers());
	}
	
	protected abstract Map<MessageCode, Handler> getMessageHandlers();
	
	/**
	 * Used to initialize the mapping in {@link MessageTranslator} between
	 * {@link MessageCode}s and {@link Message}s. 
	 * @return A {@link Map} containing these mappings.
	 */
	private final Map<MessageCode, Message> getMessageCodeMapping() {
		Map<MessageCode, Message> map = new HashMap<MessageCode, Message>();
		
		map.put(MessageCode.LOGIN_MESSAGE, new LoginMessage());
		map.put(MessageCode.LOGIN_FAILED_MESSAGE, new LoginFailedMessage());
		map.put(MessageCode.LOGIN_SUCCESSFUL_MESSAGE, new LoginSuccessfulMessage());
		map.put(MessageCode.LOGOUT_SUCCESSFUL_MESSAGE, new LogoutSuccessfulMessage());
		map.put(MessageCode.LOGOUT_MESSAGE, new LogoutMessage());
		map.put(MessageCode.ADD_OR_UPDATE_APPOINTMENT_MESSAGE, new AddOrUpdateAppointmentMessage());
		map.put(MessageCode.APPOINTMENT_ADDED_OR_UPDATED_MESSAGE, new AppointmentAddedOrUpdatedMessage());
		map.put(MessageCode.GET_EMPLOYEES_MESSAGE, new GetEmployeesMessage());
		map.put(MessageCode.EMPLOYEES_FETCHED_MESSAGE, new EmployeesFetchedMessage());
		map.put(MessageCode.GET_MEETING_ROOMS_MESSAGE, new GetMeetingRoomsMessage());
		map.put(MessageCode.NOTICE_READ_MESSAGE, new NoticeReadMessage());
		map.put(MessageCode.NOTICE_ADDED_OR_UPDATED_MESSAGE, new NoticeAddedOrUpdatedMessage());
		map.put(MessageCode.DELETE_APPOINTMENT_MESSAGE, new DeleteAppointmentMessage());
		map.put(MessageCode.APPOINTMENT_DELETED_MESSAGE, new AppointmentDeletedMessage());
		map.put(MessageCode.ADD_MEETING_MESSAGE, new AddMeetingMessage());
		map.put(MessageCode.MEETING_ADDED_MESSAGE, new MeetingAddedMessage());
		map.put(MessageCode.UPDATE_MEETING_MESSAGE, new UpdateMeetingMessage());
		map.put(MessageCode.MEETING_UPDATED_MESSAGE, new MeetingUpdatedMessage());
		map.put(MessageCode.DELETE_MEETING_MESSAGE, new DeleteMeetingMessage());
		map.put(MessageCode.MEETING_DELETED_MESSAGE, new MeetingDeletedMessage());
		map.put(MessageCode.REQUEST_APPOINTMENTS_FOR_EMPLOYEE_MESSAGE, new RequestAppointmentsForEmployeeMessage());
		map.put(MessageCode.REQUEST_MEETINGS_FOR_EMPLOYEE_MESSAGE, new RequestMeetingsForEmployeeMessage());
		map.put(MessageCode.APPOINTMENTS_FOR_EMPLOYEE_MESSAGE, new AppointmentsForEmployeeMessage());
		map.put(MessageCode.MEETINGS_FOR_EMPLOYEE_MESSAGE, new MeetingsForEmployeeMessage());
		map.put(MessageCode.ACCEPT_NOTICE_MESSAGE, new AcceptNoticeMessage());
		map.put(MessageCode.REJECT_NOTICE_MESSAGE, new RejectNoticeMessage());
		map.put(MessageCode.MEETING_ROOMS_FETCHED_MESSAGE, new MeetingRoomsFetchedMessage());
		map.put(MessageCode.MEETING_REJECTED_MESSAGE, new MeetingRejectedMessage());
		map.put(MessageCode.ALREADY_LOGGED_IN_MESSAGE, new AlreadyLoggedInMessage());
		
		return map;
	}
}
	
